<?php
class smtp {
function server_parse($socket, $response)
{
   while ( substr($server_response,3,1) != ' ' )
   {
      if( !( $server_response = @fgets($socket, 256) ) )
      {
         $this->error("Couldn't get mail server response codes");
      }
   }

   if( !( substr($server_response, 0, 3) == $response ) )
   {
      $this->error("Ran into problems sending Mail. Response: $server_response");
   }
}

/***************************************************************** Function: smtpmail
**
** Description: This is a functional replacement for php's builtin mail function, that uses smtp.
**
** Usage: The usage for this function is identical to that of php's built in mail function.
***************************************************************/

function smtpmail($mail_to, $subject, $message, $headers = "")
{

    global $smtp;

    //
    // Fix any bare linefeeds in the message to make it RFC821 Compliant.
    //
    $message = preg_replace("/(?<!\r)\n/si", "\r\n", $message);

    if ($headers != "")
    {
        if(is_array($headers))
        {
            if(sizeof($headers) > 1)
            {
                $headers = join("\r\n", $headers);
            }
            else
            {
                $headers = $headers[0];
            }
        }
        $headers = chop($headers);

        //
        // Make sure there are no bare linefeeds in the headers
        //
        $headers = preg_replace("/(?<!\r)\n/si", "\r\n", $headers);
        //
        // Ok this is rather confusing all things considered,
        // but we have to grab bcc and cc headers and treat them differently
        // Something we really didn't take into consideration originally
        //
        $header_array = explode("\r\n", $headers);
        @reset($header_array);
        $headers = "";
        while( list(, $header) = each($header_array) )
        {
            if( preg_match("/^cc:/si", $header) )
            {
                $cc = preg_replace("/^cc:(.*)/si", "\\1", $header);
            }
            else if( preg_match("/^bcc:/si", $header ))
            {
                $bcc = preg_replace("/^bcc:(.*)/si", "\\1", $header);
                $header = "";
            }
            $headers .= $header . "\r\n";
        }
        $headers = chop($headers);
        $cc = explode(",", $cc);
        $bcc = explode(",", $bcc);
    }
    if($mail_to == "")
    {
        $this->error("No email address specified");
    }
    if(trim($subject) == "")
    {
        $this->error("No email Subject specified");
    }
    if(trim($message) == "")
    {
        $this->error("Email message was blank");
    }
    if( trim($smtp['from']) == ""){
        $this->error("No FROM address specified");
    }
    $mail_to_array = explode(",", $mail_to);

    //
    // Ok we have error checked as much as we can to this point let's get on
    // it already.
    // But first check the mail server.
    //
    if(trim($smtp['host']) == "")
    {
        $smtp['host'] = "localhost";
    }

    if( !$this->socket = @fsockopen($smtp['host'], 25, $errno, $errstr, 20) )
    {
        $this->error("Could not connect to smtp host : $errno : $errstr");
        $connection_error = true;
    }

    if( !$connection_error){

    $this->server_parse($this->socket, "220");

    if( !empty($smtp['username']) && !empty($smtp['password']) )
    {
        //
        // Send the RFC2554 specified EHLO.
        // works on both SMTP AND ESMTP capable servers
        //
        fputs($this->socket, "EHLO " . $smtp['host'] . "\r\n");
        $this->server_parse($this->socket, "250");

        fputs($this->socket, "AUTH LOGIN\r\n");
        $this->server_parse($this->socket, "334");
        fputs($this->socket, base64_encode($smtp['username']) . "\r\n");
        $this->server_parse($this->socket, "334");
        fputs($this->socket, base64_encode($smtp['password']) . "\r\n");
        $this->server_parse($this->socket, "235");
    }
    else
    {
        // Send the RFC821 specified HELO.
        fputs($this->socket, "HELO " . $smtp['host'] . "\r\n");
        $this->server_parse($this->socket, "250");
    }

    // From this point onward most server response codes should be 250
    // Specify who the mail is from....

    fputs($this->socket, "MAIL FROM: <" . $smtp['from'] . ">\r\n");
    $this->server_parse($this->socket, "250");

    // Specify each user to send to and build to header.
    $to_header = "To: ";
    @reset( $mail_to_array );
    while( list( , $mail_to_address ) = each( $mail_to_array ))
    {
        //
        // Add an additional bit of error checking to the To field.
        //
        $mail_to_address = trim($mail_to_address);
        if ( preg_match('/[^ ]+\@[^ ]+/', $mail_to_address) )
        {
            fputs( $this->socket, "RCPT TO: $mail_to_address\r\n" );
            $this->server_parse( $this->socket, "250" );
        }
        $to_header .= ( ( $mail_to_address != '' ) ? ', ' : '' ) . "$mail_to_address";
    }
    // Ok now do the CC and BCC fields...
    @reset( $bcc );
    while( list( , $bcc_address ) = each( $bcc ))
    {
        //
        // Add an additional bit of error checking to bcc header...
        //
        $bcc_address = trim( $bcc_address );
        if ( preg_match('/[^ ]+\@[^ ]+/', $bcc_address) )
        {
            fputs( $this->socket, "RCPT TO: $bcc_address\r\n" );
            $this->server_parse( $this->socket, "250" );
        }
    }
    @reset( $cc );
    while( list( , $cc_address ) = each( $cc ))
    {
        //
        // Add an additional bit of error checking to cc header
        //
        $cc_address = trim( $cc_address );
        if ( preg_match('/[^ ]+\@[^ ]+/', $cc_address) )
        {
            fputs($this->socket, "RCPT TO: $cc_address\r\n");
            $this->server_parse($this->socket, "250");
        }
    }
    // Ok now we tell the server we are ready to start sending data
    fputs($this->socket, "DATA\r\n");

    // This is the last response code we look for until the end of the message.
    $this->server_parse($this->socket, "354");

    // Send the Subject Line...
    fputs($this->socket, "Subject: $subject\r\n");

    // Send the Date Line...
    fputs($this->socket, "Date: ".date('r')."\r\n");

    // Now the To Header.
    fputs($this->socket, "$to_header\r\n");

    // SMTP mail header....
    fputs($this->socket, "X-Mailer: SMTP Class\r\n");

    // Now any custom headers....
    fputs($this->socket, "$headers\r\n\r\n");

    // Ok now we are ready for the message...
    fputs($this->socket, "$message\r\n");

    // Ok the all the ingredients are mixed in let's cook this puppy...
    fputs($this->socket, ".\r\n");
    if( !$this->server_parse($this->socket, "250")){
    fputs($this->socket, "QUIT\r\n");
    fclose($this->socket);
    return false;
    }

    // Now tell the server we are done and close the socket...
    fputs($this->socket, "QUIT\r\n");
    fclose($this->socket);

    return TRUE;
    }else{
    return FALSE;
    } // End connection checking
}


/***************************************************************** Function: error
** Description: Print error messages user friendly
** Usage: Only used inside this class.
***************************************************************/

function error($message)
{
    echo $message."<br /><br />\r\n";
    $this->mail_error = 'Yes';
}

}
// End class smtp
?>